1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.base;
18
19 import com.google.common.annotations.GwtCompatible;
20 import com.google.common.annotations.GwtIncompatible;
21 import com.google.common.collect.ImmutableMap;
22 import com.google.common.collect.Maps;
23 import com.google.common.testing.ClassSanityTester;
24 import com.google.common.testing.EqualsTester;
25 import com.google.common.testing.NullPointerTester;
26 import com.google.common.testing.SerializableTester;
27
28 import junit.framework.TestCase;
29
30 import java.io.Serializable;
31 import java.util.Map;
32
33
34
35
36
37
38
39 @GwtCompatible(emulated = true)
40 public class FunctionsTest extends TestCase {
41
42 public void testIdentity_same() {
43 Function<String, String> identity = Functions.identity();
44 assertNull(identity.apply(null));
45 assertSame("foo", identity.apply("foo"));
46 }
47
48 public void testIdentity_notSame() {
49 Function<Long, Long> identity = Functions.identity();
50 assertNotSame(new Long(135135L), identity.apply(new Long(135135L)));
51 }
52
53 @GwtIncompatible("SerializableTester")
54 public void testIdentitySerializable() {
55 checkCanReserializeSingleton(Functions.identity());
56 }
57
58 public void testToStringFunction_apply() {
59 assertEquals("3", Functions.toStringFunction().apply(3));
60 assertEquals("hiya", Functions.toStringFunction().apply("hiya"));
61 assertEquals("I'm a string",
62 Functions.toStringFunction().apply(
63 new Object() {
64 @Override public String toString() {
65 return "I'm a string";
66 }
67 }));
68 try {
69 Functions.toStringFunction().apply(null);
70 fail("expected NullPointerException");
71 } catch (NullPointerException e) {
72
73 }
74 }
75
76 @GwtIncompatible("SerializableTester")
77 public void testToStringFunctionSerializable() {
78 checkCanReserializeSingleton(Functions.toStringFunction());
79 }
80
81 @GwtIncompatible("NullPointerTester")
82 public void testNullPointerExceptions() {
83 NullPointerTester tester = new NullPointerTester();
84 tester.testAllPublicStaticMethods(Functions.class);
85 }
86
87 public void testForMapWithoutDefault() {
88 Map<String, Integer> map = Maps.newHashMap();
89 map.put("One", 1);
90 map.put("Three", 3);
91 map.put("Null", null);
92 Function<String, Integer> function = Functions.forMap(map);
93
94 assertEquals(1, function.apply("One").intValue());
95 assertEquals(3, function.apply("Three").intValue());
96 assertNull(function.apply("Null"));
97
98 try {
99 function.apply("Two");
100 fail();
101 } catch (IllegalArgumentException expected) {
102 }
103
104 new EqualsTester()
105 .addEqualityGroup(function, Functions.forMap(map))
106 .addEqualityGroup(Functions.forMap(map, 42))
107 .testEquals();
108 }
109
110 @GwtIncompatible("SerializableTester")
111 public void testForMapWithoutDefaultSerializable() {
112 checkCanReserialize(Functions.forMap(ImmutableMap.of(1, 2)));
113 }
114
115 public void testForMapWithDefault() {
116 Map<String, Integer> map = Maps.newHashMap();
117 map.put("One", 1);
118 map.put("Three", 3);
119 map.put("Null", null);
120 Function<String, Integer> function = Functions.forMap(map, 42);
121
122 assertEquals(1, function.apply("One").intValue());
123 assertEquals(42, function.apply("Two").intValue());
124 assertEquals(3, function.apply("Three").intValue());
125 assertNull(function.apply("Null"));
126
127 new EqualsTester()
128 .addEqualityGroup(function, Functions.forMap(map, 42))
129 .addEqualityGroup(Functions.forMap(map))
130 .addEqualityGroup(Functions.forMap(map, null))
131 .addEqualityGroup(Functions.forMap(map, 43))
132 .testEquals();
133 }
134
135 @GwtIncompatible("SerializableTester")
136 public void testForMapWithDefault_includeSerializable() {
137 Map<String, Integer> map = Maps.newHashMap();
138 map.put("One", 1);
139 map.put("Three", 3);
140 Function<String, Integer> function = Functions.forMap(map, 42);
141
142 assertEquals(1, function.apply("One").intValue());
143 assertEquals(42, function.apply("Two").intValue());
144 assertEquals(3, function.apply("Three").intValue());
145
146 new EqualsTester()
147 .addEqualityGroup(
148 function,
149 Functions.forMap(map, 42),
150 SerializableTester.reserialize(function))
151 .addEqualityGroup(Functions.forMap(map))
152 .addEqualityGroup(Functions.forMap(map, null))
153 .addEqualityGroup(Functions.forMap(map, 43))
154 .testEquals();
155 }
156
157 @GwtIncompatible("SerializableTester")
158 public void testForMapWithDefaultSerializable() {
159 checkCanReserialize(Functions.forMap(ImmutableMap.of(1, 2), 3));
160 }
161
162 public void testForMapWithDefault_null() {
163 ImmutableMap<String, Integer> map = ImmutableMap.of("One", 1);
164 Function<String, Integer> function = Functions.forMap(map, null);
165
166 assertEquals((Integer) 1, function.apply("One"));
167 assertNull(function.apply("Two"));
168
169
170 new EqualsTester()
171 .addEqualityGroup(function)
172 .addEqualityGroup(Functions.forMap(map, 1))
173 .testEquals();
174 }
175
176 @GwtIncompatible("SerializableTester")
177 public void testForMapWithDefault_null_compareWithSerializable() {
178 ImmutableMap<String, Integer> map = ImmutableMap.of("One", 1);
179 Function<String, Integer> function = Functions.forMap(map, null);
180
181 assertEquals((Integer) 1, function.apply("One"));
182 assertNull(function.apply("Two"));
183
184
185 new EqualsTester()
186 .addEqualityGroup(function, SerializableTester.reserialize(function))
187 .addEqualityGroup(Functions.forMap(map, 1))
188 .testEquals();
189 }
190
191 public void testForMapWildCardWithDefault() {
192 Map<String, Integer> map = Maps.newHashMap();
193 map.put("One", 1);
194 map.put("Three", 3);
195 Number number = Double.valueOf(42);
196 Function<String, Number> function = Functions.forMap(map, number);
197
198 assertEquals(1, function.apply("One").intValue());
199 assertEquals(number, function.apply("Two"));
200 assertEquals(3L, function.apply("Three").longValue());
201 }
202
203 public void testComposition() {
204 Map<String, Integer> mJapaneseToInteger = Maps.newHashMap();
205 mJapaneseToInteger.put("Ichi", 1);
206 mJapaneseToInteger.put("Ni", 2);
207 mJapaneseToInteger.put("San", 3);
208 Function<String, Integer> japaneseToInteger =
209 Functions.forMap(mJapaneseToInteger);
210
211 Map<Integer, String> mIntegerToSpanish = Maps.newHashMap();
212 mIntegerToSpanish.put(1, "Uno");
213 mIntegerToSpanish.put(3, "Tres");
214 mIntegerToSpanish.put(4, "Cuatro");
215 Function<Integer, String> integerToSpanish =
216 Functions.forMap(mIntegerToSpanish);
217
218 Function<String, String> japaneseToSpanish =
219 Functions.compose(integerToSpanish, japaneseToInteger);
220
221 assertEquals("Uno", japaneseToSpanish.apply("Ichi"));
222 try {
223 japaneseToSpanish.apply("Ni");
224 fail();
225 } catch (IllegalArgumentException e) {
226 }
227 assertEquals("Tres", japaneseToSpanish.apply("San"));
228 try {
229 japaneseToSpanish.apply("Shi");
230 fail();
231 } catch (IllegalArgumentException e) {
232 }
233
234 new EqualsTester()
235 .addEqualityGroup(
236 japaneseToSpanish,
237 Functions.compose(integerToSpanish, japaneseToInteger))
238 .addEqualityGroup(japaneseToInteger)
239 .addEqualityGroup(integerToSpanish)
240 .addEqualityGroup(
241 Functions.compose(japaneseToInteger, integerToSpanish))
242 .testEquals();
243 }
244
245 @GwtIncompatible("SerializableTester")
246 public void testComposition_includeReserializabled() {
247 Map<String, Integer> mJapaneseToInteger = Maps.newHashMap();
248 mJapaneseToInteger.put("Ichi", 1);
249 mJapaneseToInteger.put("Ni", 2);
250 mJapaneseToInteger.put("San", 3);
251 Function<String, Integer> japaneseToInteger =
252 Functions.forMap(mJapaneseToInteger);
253
254 Map<Integer, String> mIntegerToSpanish = Maps.newHashMap();
255 mIntegerToSpanish.put(1, "Uno");
256 mIntegerToSpanish.put(3, "Tres");
257 mIntegerToSpanish.put(4, "Cuatro");
258 Function<Integer, String> integerToSpanish =
259 Functions.forMap(mIntegerToSpanish);
260
261 Function<String, String> japaneseToSpanish =
262 Functions.compose(integerToSpanish, japaneseToInteger);
263
264 new EqualsTester()
265 .addEqualityGroup(
266 japaneseToSpanish,
267 Functions.compose(integerToSpanish, japaneseToInteger),
268 SerializableTester.reserialize(japaneseToSpanish))
269 .addEqualityGroup(japaneseToInteger)
270 .addEqualityGroup(integerToSpanish)
271 .addEqualityGroup(
272 Functions.compose(japaneseToInteger, integerToSpanish))
273 .testEquals();
274 }
275
276 public void testCompositionWildcard() {
277 Map<String, Integer> mapJapaneseToInteger = Maps.newHashMap();
278 Function<String, Integer> japaneseToInteger =
279 Functions.forMap(mapJapaneseToInteger);
280
281 Function<Object, String> numberToSpanish = Functions.constant("Yo no se");
282
283 Function<String, String> japaneseToSpanish =
284 Functions.compose(numberToSpanish, japaneseToInteger);
285 }
286
287 private static class HashCodeFunction implements Function<Object, Integer> {
288 @Override
289 public Integer apply(Object o) {
290 return (o == null) ? 0 : o.hashCode();
291 }
292 }
293
294 public void testComposeOfFunctionsIsAssociative() {
295 Map<Float, String> m = ImmutableMap.of(
296 4.0f, "A", 3.0f, "B", 2.0f, "C", 1.0f, "D");
297 Function<? super Integer, Boolean> h = Functions.constant(Boolean.TRUE);
298 Function<? super String, Integer> g = new HashCodeFunction();
299 Function<Float, String> f = Functions.forMap(m, "F");
300
301 Function<Float, Boolean> c1 = Functions.compose(Functions.compose(h, g), f);
302 Function<Float, Boolean> c2 = Functions.compose(h, Functions.compose(g, f));
303
304
305
306
307
308 assertEquals(c1.hashCode(), c2.hashCode());
309
310 assertEquals(c1.apply(1.0f), c2.apply(1.0f));
311 assertEquals(c1.apply(5.0f), c2.apply(5.0f));
312 }
313
314 public void testComposeOfPredicateAndFunctionIsAssociative() {
315 Map<Float, String> m = ImmutableMap.of(
316 4.0f, "A", 3.0f, "B", 2.0f, "C", 1.0f, "D");
317 Predicate<? super Integer> h = Predicates.equalTo(42);
318 Function<? super String, Integer> g = new HashCodeFunction();
319 Function<Float, String> f = Functions.forMap(m, "F");
320
321 Predicate<Float> p1 = Predicates.compose(Predicates.compose(h, g), f);
322 Predicate<Float> p2 = Predicates.compose(h, Functions.compose(g, f));
323
324
325
326
327
328 assertEquals(p1.hashCode(), p2.hashCode());
329
330 assertEquals(p1.apply(1.0f), p2.apply(1.0f));
331 assertEquals(p1.apply(5.0f), p2.apply(5.0f));
332 }
333
334 public void testForPredicate() {
335 Function<Object, Boolean> alwaysTrue =
336 Functions.forPredicate(Predicates.alwaysTrue());
337 Function<Object, Boolean> alwaysFalse =
338 Functions.forPredicate(Predicates.alwaysFalse());
339
340 assertTrue(alwaysTrue.apply(0));
341 assertFalse(alwaysFalse.apply(0));
342
343 new EqualsTester()
344 .addEqualityGroup(
345 alwaysTrue, Functions.forPredicate(Predicates.alwaysTrue()))
346 .addEqualityGroup(alwaysFalse)
347 .addEqualityGroup(Functions.identity())
348 .testEquals();
349 }
350
351 @GwtIncompatible("SerializableTester")
352 public void testForPredicateSerializable() {
353 checkCanReserialize(Functions.forPredicate(Predicates.equalTo(5)));
354 }
355
356 public void testConstant() {
357 Function<Object, Object> f = Functions.<Object>constant("correct");
358 assertEquals("correct", f.apply(new Object()));
359 assertEquals("correct", f.apply(null));
360
361 Function<Object, String> g = Functions.constant(null);
362 assertEquals(null, g.apply(2));
363 assertEquals(null, g.apply(null));
364
365 new EqualsTester()
366 .addEqualityGroup(f, Functions.constant("correct"))
367 .addEqualityGroup(Functions.constant("incorrect"))
368 .addEqualityGroup(Functions.toStringFunction())
369 .addEqualityGroup(g)
370 .testEquals();
371
372 new EqualsTester()
373 .addEqualityGroup(g, Functions.constant(null))
374 .addEqualityGroup(Functions.constant("incorrect"))
375 .addEqualityGroup(Functions.toStringFunction())
376 .addEqualityGroup(f)
377 .testEquals();
378 }
379
380 @GwtIncompatible("SerializableTester")
381 public void testConstantSerializable() {
382 checkCanReserialize(Functions.constant(5));
383 }
384
385 private static class CountingSupplier
386 implements Supplier<Integer>, Serializable {
387
388 private static final long serialVersionUID = 0;
389
390 private int value;
391
392 @Override
393 public Integer get() {
394 return ++value;
395 }
396
397 @Override
398 public boolean equals(Object obj) {
399 if (obj instanceof CountingSupplier) {
400 return this.value == ((CountingSupplier) obj).value;
401 }
402 return false;
403 }
404
405 @Override
406 public int hashCode() {
407 return value;
408 }
409 }
410
411 public void testForSupplier() {
412 Supplier<Integer> supplier = new CountingSupplier();
413 Function<Object, Integer> function = Functions.forSupplier(supplier);
414
415 assertEquals(1, (int) function.apply(null));
416 assertEquals(2, (int) function.apply("foo"));
417
418 new EqualsTester()
419 .addEqualityGroup(function, Functions.forSupplier(supplier))
420 .addEqualityGroup(Functions.forSupplier(new CountingSupplier()))
421 .addEqualityGroup(Functions.forSupplier(Suppliers.ofInstance(12)))
422 .addEqualityGroup(Functions.toStringFunction())
423 .testEquals();
424 }
425
426 @GwtIncompatible("SerializableTester")
427 public void testForSupplierSerializable() {
428 checkCanReserialize(Functions.forSupplier(new CountingSupplier()));
429 }
430
431 @GwtIncompatible("reflection")
432 public void testNulls() throws Exception {
433 new ClassSanityTester().forAllPublicStaticMethods(Functions.class).testNulls();
434 }
435
436 @GwtIncompatible("reflection")
437 public void testEqualsAndSerializable() throws Exception {
438 new ClassSanityTester().forAllPublicStaticMethods(Functions.class).testEqualsAndSerializable();
439 }
440
441 @GwtIncompatible("SerializableTester")
442 private static <Y> void checkCanReserialize(Function<? super Integer, Y> f) {
443 Function<? super Integer, Y> g = SerializableTester.reserializeAndAssert(f);
444 for (int i = 1; i < 5; i++) {
445
446 Y expected = null;
447 try {
448 expected = f.apply(i);
449 } catch (IllegalArgumentException e) {
450 try {
451 g.apply(i);
452 fail();
453 } catch (IllegalArgumentException ok) {
454 continue;
455 }
456 }
457 assertEquals(expected, g.apply(i));
458 }
459 }
460
461 @GwtIncompatible("SerializableTester")
462 private static <Y> void checkCanReserializeSingleton(Function<? super String, Y> f) {
463 Function<? super String, Y> g = SerializableTester.reserializeAndAssert(f);
464 assertSame(f, g);
465 for (Integer i = 1; i < 5; i++) {
466 assertEquals(f.apply(i.toString()), g.apply(i.toString()));
467 }
468 }
469
470 }